package com.teradata.feedProc.beans;

import java.util.HashMap;
import java.util.Map;

public class DateFormats {

	private static Map<String, String> dateFormats;
	private static Map<String, String> excepFormats;
	private static Map<String, Integer> formattedString;

	/**
	 * When a DateFormats object is created, the HashMap excepFormats is loaded
	 * will all of the formats that do not follow a default java DateFormat.
	 */
	public DateFormats() {
		dateFormats = new HashMap<String, String>();
		excepFormats = new HashMap<String, String>();
		formattedString = new HashMap<String, Integer>();
		// load the map
		loadDateFormats();
		loadExceptionFormats();
		loadFormattedString();
	}

	/**
	 * Takes the format from the source file, and matches it with a java
	 * DateFormat that can be used to create a date object. Returns the
	 * DateFormat that corresponds with the format given.
	 * 
	 * @param format
	 *            The format of the date given by the source file.
	 * @return a string containing the java DateFormat that matches the format
	 *         given by the source file.
	 */
	public static String findJavaFormat(String format) {
		// first check in exception formats and return if find one there
		if (excepFormats.containsKey(format)) {
			return excepFormats.get(format);
		}
		// must be a regular format; lets look in our array for regular formats
		else if (dateFormats.containsKey(format)) {
			return dateFormats.get(format);
		} else {
			return null;
		}
	}

	/**
	 * If the format string contains any characters that are not recognized by
	 * the java DateFormat, the string returned is date value that was read from
	 * the source file, after removing the foreign characters.
	 * 
	 * @param strValue
	 *            The date value taken from the source file.
	 * @param strFormat
	 *            The format given by the source file.
	 * @return The format that will be used to create a Date object.
	 */
	public static String getFormattedString(String strValue, String strFormat) {
		if (excepFormats.containsKey(strFormat)) {
			strValue = strValue.substring(0, strValue.length() - formattedString.get(strFormat));
			return strValue;
		} else {
			return null;
		}
	}

	// Formats that are paired with the correct syntax of that format
	private static void loadDateFormats() {
		dateFormats.put("YYYY-MM-DD", "yyyy-MM-dd");
		dateFormats.put("YY-MM-DD", "yy-MM-dd");
		dateFormats.put("YYYY-MM-DDBHH24:MI:SS", "yyyy-MM-dd HH:mm:ss");
		dateFormats.put("MMMBD?BYYYY", "MMM d? yyyy");
		dateFormats.put("YYYY-M?-D?", "yyyy-M?-d?");
		dateFormats.put("YYYY/M?/D?", "yyyy/M?/D?");
		dateFormats.put("MMM D? YYYY", "MMM d? yyyy");
		dateFormats.put("M?/D?/YYYY", "M?/d?/yyyy");
		dateFormats.put("D?/M?/YYYY", "d?/M?/yyyy");
		dateFormats.put("DD/MM/YYYYBHH:MI", "dd/MM/yyyy HH:mm");
		dateFormats.put("YYYY-MM-DDBHH24:MI", "yyyy-MM-dd HH:mm");
		dateFormats.put("YYYYMMDDHHMISS", "yyyyMMddHHmmss");
		dateFormats.put("MMDDYYYYHHMISS", "MMddyyyyHHmmss");
		dateFormats.put("HH24MISS", "HHmmss");
		dateFormats.put("DDMMYYYY", "ddMMyyyy");
		dateFormats.put("DDMMYY", "ddMMyy");
		dateFormats.put("YYYY/MM/DDBHH:MI:SS", "yyyy/MM/dd HH:mm:ss");
		dateFormats.put("YYYY/DD/MM HH24:MI:SS", "yyyy/dd/MM HH:mm:ss");
		dateFormats.put("MMDDYY", "MMddyy");
		dateFormats.put("YYYYDDD", "yyyyDDD");
		dateFormats.put("YYYY/MM/DD", "yyyy/MM/dd");
		dateFormats.put("HH24:MI:SS", "HH:mm:ss");
		dateFormats.put("DD.MM.YYYY", "dd.MM.yyyy");
		dateFormats.put("MMDDYYYYBHH24:MI:SS", "MMddyyyy HH:mm:ss");
		dateFormats.put("YYMMDDHHMISS", "yyMMddHHmmss");
		dateFormats.put("HH:MI:SS", "HH:mm:ss");
		dateFormats.put("YYMMDD", "yyMMdd");
		dateFormats.put("YYYYMMDD", "yyyyMMdd");
		dateFormats.put("MMMBDDBYYYY", "MMM dd yyyy");
		dateFormats.put("mm-dd-yyyy", "MM-dd-yyyy");
		dateFormats.put("YYYY-MM-DDBHH:MI:SS", "yyyy-MM-dd HH:mm:ss");
		dateFormats.put("YYYY-MM-DD", "yyyy-MM-dd");
		dateFormats.put("MMDDYYYY", "MMddyyyy");
		dateFormats.put("MM/DD/YYYYBHH:MI:SS", "MM/dd/yyyy HH:mm:ss");
		dateFormats.put("YYYY-MM-DD HH:MI:SS", "yyyy-MM-dd HH:mm:ss");
		dateFormats.put("MMMBDDBYYYYBHH24:MI:SS", "MMM dd yyyy HH:mm:ss");
		dateFormats.put("DD-MMM-YY", "dd-MMM-yy");
		dateFormats.put("MM/DD/YYYY", "MM/dd/yyyy");
		dateFormats.put("MM/DD/YY", "MM/dd/yy");
		dateFormats.put("YYYYJJJ", "yyyyDDD");
		dateFormats.put("YYJJJ", "yyDDD");
		dateFormats.put("DD-MMM-YYYY-HHMISS", "dd-MMM-yyyy-HHmmss");
		dateFormats.put("YYYY-MM-DD HH24:MI:SS", "yyyy-MM-dd HH:mm:ss");
		dateFormats.put("YYDDD", "yyDDD");
		dateFormats.put("YY/MM/DD", "yy/MM/dd");
		dateFormats.put("DD-MM-YYYY", "dd-MM-yyyy");
		dateFormats.put("HHMISS", "HHmmss");
		dateFormats.put("DD-MMM-YYYY HH24:MI:SS", "dd-MMM-yyyy HH:mm:ss");
		dateFormats.put("MMMDDYYYY", "MMMddyyyy");
		dateFormats.put("DD MMM YYYY", "dd MMM yyyy");
		dateFormats.put("MMM DD YY", "MM dd yy");
		dateFormats.put("MMM DD YYYY", "MMM dd yyyy");
		dateFormats.put("MM-DD-YY", "MM-dd-yy");
		dateFormats.put("MM DD YY", "MM dd yy");
		dateFormats.put("YY-MM-DDBHH24:MI:SS", "yy-MM-dd HH:mm:ss");
		dateFormats.put("YYMMDDBHH24:MI:SS.NNN", "yyMMdd HH:mm:ss.SSS");
		dateFormats.put("YYYY-MM-DDBHH24:MI:SS.S(3)", "yyyy-MM-dd HH:mm:ss.SSS");
		dateFormats.put("YYYYMMDDBHH24:MI:SS.NNN", "yyyyMMdd HH:mm:ss.SSS");
		dateFormats.put("MM/DD/YYYY HH24:MI:SS.NNN", "MM/dd/yyyy HH:mm:ss.SSS");
		dateFormats.put("YYYY-MM-DDBHH:MI:S.S(3)", "yyyy-MM-dd HH:mm:ss.SSS");
		dateFormats.put("YYYY-MM-DDBHH24:MI:SS.NNN", "yyyy-MM-dd HH:mm:ss.SSS");
		dateFormats.put("YYYY-MM-DDBHH:MI:SS.NNN", "yyyy-MM-dd HH:mm:ss.SSS");
		dateFormats.put("YYYYMMDD HH24:MI:SS.NNN", "yyyyMMdd HH:mm:ss.SSS");
		dateFormats.put("YYYY-MM-DD HH24:MI:SS.S(3)", "yyyy-MM-dd HH:mm:ss.SSS");
		dateFormats.put("MM/DD/YYYY HH:MI:SS.NNN", "MM/dd/yyyy HH:mm:ss.SSS");
		dateFormats.put("YYYY-MM-DD HH24:MI:SS.NNN", "yyyy-MM-dd HH:mm:ss.SSS");
		dateFormats.put("YYMMDD HH24:MI:SS.NNN", "yyMMdd HH:mm:ss.SSS");
		dateFormats.put("MMMBDDBYYYYBHH24:MI:SS:NNN", "MMM dd yyyy HH:mm:ss.SSS");
		dateFormats.put("HHMISST", "hhmmssaa");
		dateFormats.put("MMMBDDBYYYYBHH:MI:SS.NNNT", "MMM dd yyyy hh:mm:ss.SSSaa");
		dateFormats.put("DD-MM-YY HH:MI:SS T", "dd-MM-yy hh:mm:ss aa");
		dateFormats.put("YYYYMMDDHHMISST", "yyyyMMddhhmmssaa");
		dateFormats.put("YYYY-MM-DDBHH:MI:SS.NNNBT", "yyyy-MM-dd hh:mm:ss.SSS aa");
		dateFormats.put("YYYY-MM-DDBHH:MI:SSBT", "yyyy-MM-DD hh:mm:ss aa");
		dateFormats.put("MMMBDDBYYYYBHH:MIBT", "MMM dd yyyy hh:mm aa");
		dateFormats.put("MMM DD YYYY HH:MI:SS:NNNPM", "MMM dd yyyy hh:mm:ss.SSSaa");
		dateFormats.put("MMMBDDBYYYYBHH:MIT", "MMM dd yyyy hh:mmaa");
		dateFormats.put("DD MM YY", "dd MM yy");
		dateFormats.put("DD.MM.YY", "dd.MM.yy");
		dateFormats.put("DD-MM-YY", "dd-MM-yy");
		dateFormats.put("DD/MM/YY", "dd/MM/yy");
		dateFormats.put("DDMMYYYY", "ddMMyyyy");
		dateFormats.put("DD MM YYYY", "dd MM yyyy");
		dateFormats.put("DD/MM/YYYY", "dd/MM/yyyy");
		dateFormats.put("MM.DD.YYYY", "MM.dd.yyyy");
		dateFormats.put("MMMDD YYYY HH24:MI:SS", "MMMdd yyyy HH:mm:ss");
		dateFormats.put("YYYY/MM/DD HH:MI:SS", "yyyy/MM/dd HH:mm:ss");
		dateFormats.put("YYYY/DD/MM HH24:MI:SS", "yyyy/dd/MM HH:mm:ss");
		dateFormats.put("YYYY-MM-DD-HH:MI:SS", "yyyy-MM-dd-HH:mm:ss");
		dateFormats.put("MM.DD.YY HH:MI:SS", "MM.dd.yy HH:mm:ss");
		dateFormats.put("DDMMYYYY HH:MI:SS.NNN", "ddMMyyyy HH:mm:ss.SSS");
		dateFormats.put("DD/MM/YYYY HH:MI", "dd/MM/yyyy HH:mm");
		dateFormats.put("DD-MMM-YYYY-HHMISS", "dd-MMM-yyyy-HHmmss");
		dateFormats.put("YYMMDD HH:MI:SS", "yyMMdd HH:mm:ss");
		dateFormats.put("MMMBDDBYYYYBHH24:MI:SS.NNN", "MMM dd yyyy HH:mm:ss.SSS");
		dateFormats.put("YYYYMMDDBHH:MI:SS.NNN", "yyyyMMdd HH:mm:ss.SSS");
		dateFormats.put("YYYY-MM-DDHH24:MI:SS.NNN", "yyyy-MM-ddHH:mm:ss.SSS");
		dateFormats.put("MMMBDDBYYYYBHH:MI:SS.NNNBT", "MMM dd yyyy hh:mm:ss.SSS aa");
		dateFormats.put("YYYYMMDD HH:MI:SS.NNN", "yyyMMdd HH:mm:ss.SSS");
		dateFormats.put("YYYY MM DD", "yyyy MM dd");
		dateFormats.put("YYYY MM DD HH:MI:SS", "yyyy MM dd HH:mm:ss");
		dateFormats.put("MM-DD-YY", "mm-dd-YY");
		dateFormats.put("MM-DD-YYYY", "MM-dd-yyyy");
		dateFormats.put("MM DD YY", "MM dd yy");
		dateFormats.put("YYYY.MM.DD", "yyyy.MM.dd");
		dateFormats.put("YY-MM-DD", "yy-MM-dd");
		dateFormats.put("YYDD", "yydd");
		dateFormats.put("YYMM", "yyMM");
		dateFormats.put("YYYYMM", "yyyyMM");
	}

	// Formats that contain characters that Java can not translate into a date.
	// Paired with a date format that will match the date without the extra
	// characters
	private static void loadExceptionFormats() {
		excepFormats.put("DD/MM/YYYYBHH:MI:SS.S(6)", "dd/MM/yyyy HH:mm:ss");
		excepFormats.put("YYYY-MM-DDBHH24:MI:SS.NNNNNN", "yyyy-MM-dd HH:mm:ss");
		excepFormats.put("YYYY-MM-DD-HH.MI.SS.S(6)BZ", "yyyy-MM-dd-HH.mm.ss");
		excepFormats.put("YYYYMMDDBHH24:MI:SS.NNNNNN", "yyyyMMdd HH:mm:ss");
		excepFormats.put("YYYY-MM-DD HH:MI:SS.NNNNNN", "yyyy-MM-dd HH:mm:ss");
		excepFormats.put("MM/DD/YYYY HH:MI:SS:SSSSSS", "MM/dd/yyyy HH:mm:ss");
		excepFormats.put("YYYY-MM-DD-HH:MI:SS.S(6)", "yyyy-MM-dd-HH:mm:ss");
		excepFormats.put("YYYY-MM-DD-HH24.MI.SS.NNNNNN", "yyyy-MM-dd-HH:mm:ss");
		excepFormats.put("YYYYMMDDBHH:MI:SS.S(F)Z", "yyyyMMdd HH:mm:ss");
		excepFormats.put("YYYY-MM-DDBHH:MI:SS.NNNNNNT", "yyyy-MM-dd HH:mm:ss");
		excepFormats.put("YYYY-MM-DDBHH:MI:SS.S(6)", "yyyy-MM-dd HH:mm:ss");
		excepFormats.put("HH24:MI:SS.NNNNNN", "HH:mm:ss");
		excepFormats.put("YYYY-MM-DD HH:MM:SS.SSSXM", "yyyy-MM-dd HH:mm:ss.SSS");
		excepFormats.put("YYYY-MM-DDBHH:MI:SS.NNNNNN", "yyyy-MM-dd HH:mm:ss");
		excepFormats.put("HH:MI:SS.NNNNNN", "HH:mm:ss");
		excepFormats.put("YYYYMMDDBHH:MI:SS.NNNNNN", "yyyyMMdd HH:mm:ss");
	}

	// For dates with characters that Java cannot convert, drop the characters
	// so Java will accept the date
	private static void loadFormattedString() {
		formattedString.put("DD/MM/YYYYBHH:MI:SS.S(6)", 7);
		formattedString.put("YYYY-MM-DDBHH24:MI:SS.NNNNNN", 7);
		formattedString.put("YYYY-MM-DD-HH.MI.SS.S(6)BZ", 10);
		formattedString.put("YYYYMMDDBHH24:MI:SS.NNNNNN", 7);
		formattedString.put("YYYY-MM-DD HH:MI:SS.NNNNNN", 7);
		formattedString.put("MM/DD/YYYY HH:MI:SS:SSSSSS", 7);
		formattedString.put("YYYY-MM-DD-HH:MI:SS.S(6)", 7);
		formattedString.put("YYYY-MM-DD-HH24:MI:SS.NNNNNN", 7);
		formattedString.put("YYYYMMDDBHH:MI:SS.S(F)Z", 9);
		formattedString.put("YYYY-MM-DDBHH:MI:SS.NNNNNNT", 9);
		formattedString.put("YYYY-MM-DDBHH:MI:SS.S(6)", 7);
		formattedString.put("HH24:MI:SS.NNNNNN", 7);
		formattedString.put("YYYY-MM-DD HH:MM:SS.SSSXM", 2);
		formattedString.put("YYYY-MM-DDBHH:MI:SS.NNNNNN", 7);
		formattedString.put("HH:MI:SS.NNNNNN", 7);
		formattedString.put("YYYYMMDDBHH:MI:SS.NNNNNN", 7);
	}
}